home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / mg / ri / mgridraw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-08  |  25.0 KB  |  904 lines

  1. #include "mgP.h"
  2. #include "mgriP.h"
  3. #include "polylistP.h"
  4.  
  5. #include <stdlib.h>
  6.  
  7. void    mgri_polygon( int nv, HPoint3 *v, int nn, Point3 *n,
  8.                         int nc,ColorA *c );
  9. void    mgri_mesh( int wrap,int nu,int nv,HPoint3 *p, Point3 *n,ColorA *c );
  10. void    mgri_line( HPoint3 *p1, HPoint3 *p2 );
  11. void    mgri_polyline( int nv, HPoint3 *verts, int nc, ColorA *colors,
  12.                 int wrapped );
  13. void    mgri_polylist(  int np, Poly *p, int nv, Vertex *v, 
  14.                  int plflags );
  15. void    mgri_drawnormal(HPoint3 *p, Point3 *n, Color* c);
  16.  
  17. void    mgri_drawPline(HPoint3 *p1, HPoint3 *p2);
  18.              
  19.  
  20. /*-----------------------------------------------------------------------
  21.  * Function:    mgri_polygon
  22.  * Description:    draw a polygon
  23.  * Author:    wisdom
  24.  * Date:    Fri Jan 10 13:57:53 CST 1992
  25.  * Notes:    See mg.doc.
  26.  *
  27.  */
  28. void
  29. mgri_polygon(int nv,  HPoint3 *V, 
  30.          int nn,  Point3 *N, 
  31.          int nc,  ColorA *C)
  32. {
  33.   register int i, j;    
  34.   register HPoint3 *v;
  35.   register Point3 *n;
  36.   register Color *c;
  37.   register ColorA *c4;
  38.   HPoint3 hpt;
  39.   int flag;
  40.   int shading;
  41.   int ninc;
  42.   short colorsdefined;
  43.   short normalsdefined;
  44.   short attrblock = 0;
  45.  
  46.     flag = _mgc->astk->ap.flag;
  47.     if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
  48.     nc = 0;
  49.     
  50.     shading = _mgc->astk->ap.shading;
  51.     ninc = (nn > 1);
  52.     
  53.     if(nc == 0) {
  54.       C = (ColorA*)&_mgc->astk->ap.mat->diffuse;
  55.     }
  56.  
  57.     CHECK_VCN(nv,nc,nn); /* check nv,nc,nn for overflow */
  58.     
  59.     /* Process input into a form renderman likes */
  60.     
  61.     
  62.     /* Points */ 
  63.     /* NOTE: although ri reference states that points may be described   */
  64.     /* with a 4-vector (x,y,z,w) ala the "Pw" token, I can't seem to get */
  65.     /* it to work with either Photorealistic or Quick Renderman. sw      */
  66.     if(nv>0)
  67.     for(i = 0; i < nv; i++) mgri_normalize(&V[i], ript[i]);
  68.  
  69.     if(flag & APF_FACEDRAW) {
  70.         /* RGB Color */
  71.     if (nc>0) {
  72.         if(nc==1) {
  73.         RiAttributeBegin();
  74.         attrblock=1;
  75.         RiColor(C);
  76.         colorsdefined = 0;
  77.         } else for(i = 0; i < nv; i++) {
  78.         *(Color *)&ricolor[i] = *(Color *)&C[i];
  79.         colorsdefined = 1;
  80.         }
  81.     } else colorsdefined = 0;
  82.     
  83.     /* Opacity is not supported by QRMan, so it is not handled here */
  84.     
  85.     /* Normals - do not supply with flat shading (constant */
  86.     /* interpolation) as this seems to confuse QRMAN       */
  87.     normalsdefined = 0;
  88.     if(shading!=APF_FLAT && shading!=APF_CONSTANT && nn>0) {
  89.         for(i = 0; i < nv; i++) {
  90.         if(nn>1) *(Point3 *)&rinormal[i] = N[i];
  91.         else bcopy((char *)N, (char *)rinormal[i], sizeof(float)*3);
  92.         }
  93.         normalsdefined = 1;
  94.     }
  95.         
  96.     /* Define the polygon via the renderman interface */
  97.     if(!colorsdefined && normalsdefined)
  98.         RiPolygon(nv, RI_P, (RtPointer)ript, RI_N, (RtPointer)rinormal,
  99.                   RI_NULL);
  100.     else if(colorsdefined && !normalsdefined)
  101.         RiPolygon(nv, RI_P, (RtPointer)ript, RI_CS, (RtPointer)ricolor,
  102.                   RI_NULL);
  103.     else if(!colorsdefined && !normalsdefined)
  104.         RiPolygon(nv, RI_P, (RtPointer)ript, RI_NULL);
  105.     else RiPolygon(nv, RI_P, (RtPointer)ript, RI_CS, (RtPointer)ricolor,
  106.         RI_N, (RtPointer)rinormal, RI_NULL);
  107.     }
  108.     
  109.     /* Draw Edges */
  110.     if(flag & APF_EDGEDRAW) {
  111.     Transform newbie;
  112.     float dis;
  113.     c = &_mgc->astk->ap.mat->edgecolor;
  114.     RiAttributeBegin();
  115.  
  116.     /* translate object slightly closer to camera */
  117.     mgri_closer();
  118.                 
  119.     /* now draw it */
  120.     RiColor((float *)c);
  121.     RiGeometricRepresentation("lines");
  122.     RiPolygon(nv, RI_P, (RtPointer)ript, RI_NULL);
  123.     RiAttributeEnd();
  124.     }
  125.     
  126.     /* Draw Normals */
  127.     if(flag & APF_NORMALDRAW) {
  128.     Color *color = &_mgc->astk->mat.normalcolor;
  129.     RiAttributeBegin();
  130.     RiSurface(RI_CONSTANT, RI_NULL);
  131.     RiColor((float *)color);
  132.     for (n = N, v = V, i = 0; i<nv; ++i, ++v, n += ninc)
  133.     mgri_drawnormal(v, n, color);
  134.     RiAttributeEnd();
  135.     }
  136.     
  137.     if(attrblock) RiAttributeEnd();
  138. }
  139.  
  140. /*-----------------------------------------------------------------------
  141.  * Function:    mgri_line
  142.  * Description:    draws a line
  143.  * Author:    wisdom
  144.  * Date:    Fri Jan 17 14:31:06 CST 1992
  145.  * Notes:    see mg.doc
  146.  */
  147. void mgri_line( HPoint3 *p1, HPoint3 *p2)
  148. {
  149.     /* lines in QuickRenderman inherit surface properties. */
  150.     /* we make sure they are drawn with a constant surface */
  151.     RiAttributeBegin();
  152.     RiSurface(RI_CONSTANT, RI_NULL);
  153.     mgri_drawline(p1,p2,&_mgc->astk->mat.edgecolor);
  154.     RiAttributeEnd();
  155. }
  156.  
  157. /* following passes lines through rman interface */
  158. void mgri_plflush(void)
  159. {
  160.     RiAttributeBegin();
  161.  
  162.     RiShadingInterpolation(RI_SMOOTH); /* hack to color lines correctly */
  163.     RiSurface(RI_CONSTANT, RI_NULL);
  164.     RiPointsLines(_mgric->plni, (RtPointer)plvca, (RtPointer)plvia,
  165.     RI_P, (RtPointer)plp, RI_CS, (RtPointer)plc, RI_NULL);
  166.  
  167.     RiAttributeEnd();
  168.  
  169.     _mgric->plni = 0;
  170.     _mgric->plvi = 0;
  171. }
  172.  
  173. /*-----------------------------------------------------------------------
  174.  * Function:    mgri_polyline
  175.  * Description:    draws a Polyline
  176.  * Author:    wisdom
  177.  * Date:    Fri Nov  5 14:29:45 CST 1993
  178.  * Notes:    see mg.doc
  179.  *        Feeding too many verticees into the QRMAN 3.0 interface
  180.  *        can cause bad window server crashes. To avoid this,
  181.  *        all geometry is chunked into smaller pieces. No
  182.  *        sharing of verticees is done because there is no 'master
  183.  *        array' of verticees to facilitate this - this array is
  184.  *        broken down. So, we copy and assign verticees as needed.
  185.  *        In addition to breaking geometry down, this routine will
  186.  *        buffer smaller and individual geometry, avoiding a QRMAN
  187.  *        interface call until absolutely needed. This provides better
  188.  *        performance than multiple QRMAN interface calls.
  189.  *            NOTE: This will be re-written to take full advantage of
  190.  *        NS3.1 or greater
  191.  */
  192. void mgri_polyline( int nv, HPoint3 *V, int nc, ColorA *C, int flags )
  193. {
  194.     int i;
  195.     ColorA *color;
  196.     short colorsdefined = 0;
  197.     RtColor wrapcolor[2];
  198.     RtPoint wrappoint[2];
  199.     int wrapped = flags & 1;
  200.     Color *basecolor;
  201.     short baseinc;
  202.  
  203. //    if(_mgric->plvi+nv > PLBUFFSIZE) {
  204. //        /* We need to flush the buffers */    
  205. //    mgri_plflush();
  206. //    }
  207.     
  208.     if(_mgc->astk->mat.override & MTF_EDGECOLOR)
  209.     nc = 0;
  210.  
  211.     if(nc==0) {
  212.     basecolor = (Color *)&_mgc->astk->mat.edgecolor;
  213.     baseinc = 0;
  214.     } else if(nc==1) {
  215.     basecolor = (Color *)&C[0];
  216.     baseinc = 0;
  217.     } else {
  218.     basecolor = (Color *)&C[0];
  219.     baseinc = 1;
  220.     }
  221.  
  222.     /* process points */
  223.  
  224.     if(nv>1) {
  225.     for(i = 0; i < nv-1; i++) {
  226.         plvca[_mgric->plni++] = 2;
  227.         plvia[_mgric->plvi] = _mgric->plvi;
  228.         plvia[_mgric->plvi+1] = _mgric->plvi+1;
  229.         mgri_normalize(&V[i], plp[_mgric->plvi]);
  230.         mgri_normalize(&V[i+1], plp[_mgric->plvi+1]);
  231.         *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor;
  232.         *(Color *)&plc[_mgric->plvi+1] = *(Color *)(basecolor+baseinc);
  233.         _mgric->plvi+=2;
  234.         basecolor += baseinc;
  235.         if(_mgric->plvi> _mgric->plbuffsize) mgri_plflush();
  236.     }
  237.     plvca[_mgric->plni++] = 2;
  238.     plvia[_mgric->plvi] = _mgric->plvi;
  239.     plvia[_mgric->plvi+1] = _mgric->plvi+1;
  240.     mgri_normalize(&V[i-1], plp[_mgric->plvi]);
  241.     mgri_normalize(&V[i], plp[_mgric->plvi+1]);
  242.     *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor;
  243.     *(Color *)&plc[_mgric->plvi+1] = *(Color *)(basecolor+baseinc);
  244.     _mgric->plvi+=2;
  245.     basecolor += baseinc;    
  246.     }
  247.    
  248.     if(nv==1) {
  249.         /* This is a single point. Notice that we do not define the
  250.     *  vertex only once. Tests indicate that color is not propperly
  251.     *  assigned to a point if only a single vertex is used to define
  252.     *  it. However, two equal verticees appears to overcome this
  253.     *  potential problem.
  254.     */
  255.     plvca[_mgric->plni] = 2;
  256.     plvia[_mgric->plvi] = _mgric->plvi;
  257.     plvia[_mgric->plvi+1] = _mgric->plvi+1;
  258.     mgri_normalize(&V[0], plp[_mgric->plvi]);
  259.     *(Point3 *)&plp[_mgric->plvi+1] = *(Point3 *)&plp[_mgric->plvi];
  260.     /* mgri_normalize(&V[0], plp[_mgric->plvi+1]); */
  261.     *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor;
  262.     *(Color *)&plc[_mgric->plvi+1] = *(Color *)basecolor;
  263.     _mgric->plni++;
  264.     _mgric->plvi+=2;
  265.     if(_mgric->plvi> _mgric->plbuffsize) mgri_plflush();
  266.     } 
  267.  
  268.     else if(wrapped) {
  269.         plvca[_mgric->plni] = 2;
  270.     plvia[_mgric->plvi] = _mgric->plvi;
  271.     plvia[_mgric->plvi+1] = _mgric->plvi+1;
  272.     mgri_normalize(&V[0], plp[_mgric->plvi]);
  273.     mgri_normalize(&V[nv-1], plp[_mgric->plvi+1])
  274.     *(Color *)&plc[_mgric->plvi] = *(Color *)basecolor;
  275.     *(Color *)&plc[_mgric->plvi+1] = *(Color *)basecolor;
  276.     _mgric->plni++;
  277.     _mgric->plvi+=2;
  278.     if(_mgric->plvi > _mgric->plbuffsize) mgri_plflush();
  279.     }
  280. }
  281.  
  282.  
  283. /*-----------------------------------------------------------------------
  284.  * Function:    mgri_polylist
  285.  * Description:    draws a Polylist: linked list of Polys
  286.  * Author:    wisdom
  287.  * Date:    Fri Nov  5 14:32:04 CST 1993
  288.  * Notes:
  289.  * mgri_polylist provides three primary methods to draw polyhedra:
  290.  * Currently, number 3 is used.
  291.  *    1. Seperate Polygons
  292.  *       _mgric->polymode == MGRI_POLYGONS (OBSOLETE)
  293.  *        Advantage: Colors and Normals can be properly utilized.
  294.  *         Also, MUCH less likely to crash the Windowserver.
  295.  *        Disadvantage: *SLOW*
  296.  *    2. (single/multiple) RiPointsPolygons call(s)
  297.  *       _mgric->polymode == MGRI_POINTSPOLYGONS
  298.  *        Advantage: An order of magnitude faster for large polyhedra.
  299.  *        Disadvantage: VERY unstable(NS3.0), but some failsafes are set
  300.  *        by default (via the context). When QRMan matures, all
  301.  *        safegaurds should be removed. Also, per polygon normals cannot
  302.  *        be realized by RiPointsPolygons so QRMan computes vertex
  303.  *        normals.
  304.  *     3. Devided Polylist
  305.  *        _mgric->polymode == MGRI_DEVIDEDPOLYLIST
  306.  *            The geometry is broken into peices, and fed one piece
  307.  *        at a time through the QRMan interface.
  308.  *
  309.  */
  310. void mgri_polylist( int np, Poly *P, int nv, Vertex *V, int plflags )
  311. {
  312.   register int i,j;
  313.   register Poly *p;
  314.   register Vertex **v, *vp;
  315.   register Point3 *n;
  316.   HPoint3 hpt;
  317.   int flag,shading;
  318.   Color *color;
  319.   ColorA *colorA;
  320.   int colorsdefined;
  321.   int normalsdefined;
  322.   int nc = nv;
  323.   int nn = nv;
  324.   int nvert;
  325.   int ppi; //points polygon index
  326.   int pvi; //points vertex index
  327.   
  328.   static int first = 0;  
  329.  
  330.     flag = _mgc->astk->ap.flag;
  331.     shading = _mgc->astk->ap.shading;
  332.  
  333. /*
  334.     if (shading & APF_CONSTANT) plflags &= ~(PL_HASVN|PL_HASPN);
  335.     else if (shading & APF_FLAT) plflags &= ~PL_HASVN;
  336.     else if (shading & APF_SMOOTH) plflags &= ~PL_HASPN;
  337. */
  338.  
  339.  
  340. //Following was added at the last second in attempt to make
  341. //overide work. I guess this has changed, I'm not sure if this
  342. //sniglet from the gl code is all that is needed
  343.  
  344.   switch(shading) {
  345.   case APF_FLAT: plflags &= ~PL_HASVN; break;
  346.   case APF_SMOOTH: plflags &= ~PL_HASPN; break;
  347.   default: plflags &= ~(PL_HASVN|PL_HASPN); break;
  348.   }
  349.  
  350.   if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader) 
  351.     plflags &= ~(PL_HASVCOL | PL_HASPCOL);
  352.  
  353.     CHECK_VCN(nv,nv,nn);
  354.     
  355.     if(_mgric->polymode == MGRI_POLYGONS) {
  356.     
  357.     if (flag & APF_FACEDRAW) {
  358.         RiAttributeBegin();
  359.         for (p = P, i = 0; i < np; i++, p++) {
  360.         
  361.         /* per polygon color */
  362.         if (plflags & PL_HASPCOL)
  363.             RiColor((float *)&p->pcol);
  364.         
  365.         /* Points */
  366.         for (j=0, v=p->v; j < p->n_vertices; j++, v++) {
  367.             mgri_normalize(&(*v)->pt, ript[j]);
  368.         }
  369.                 
  370.         /* colors, if supplied */
  371.         if(plflags & PL_HASVCOL) {
  372.             for (j=0, v=p->v; j < p->n_vertices; j++, v++)
  373.             *(Color *)&ricolor[j] = *(Color *)&(*v)->vcol;
  374.             colorsdefined=1;
  375.         }
  376.         else colorsdefined=0;
  377.         
  378.         /* Opacity is not yet supported by Quick Renderman */
  379.         
  380.         /* Normals - do not supply with flat shading (constant */
  381.         /* interpolation) as this seems to confuse QRMAN       */
  382.         normalsdefined=0;
  383.         if(shading!=APF_FLAT) {
  384.             if(plflags & PL_HASVN) {
  385.             for (j=0, v=p->v; j < p->n_vertices; j++, v++)
  386.                 *(Point3 *)&rinormal[j] = (*v)->vn;
  387.             normalsdefined=1;
  388.             } else if(plflags & PL_HASPN) {
  389.             for(j=0, v=p->v; j< p->n_vertices; j++, v++)
  390.                 *(Point3 *)&rinormal[j] = p->pn;
  391.             normalsdefined=1;
  392.             }
  393.         }
  394.         
  395.         /* Define the polygon via the renderman interface */
  396.         if(!colorsdefined && normalsdefined)
  397.             RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_N,
  398.                 (RtPointer)rinormal, RI_NULL);
  399.         else if(colorsdefined && !normalsdefined)
  400.             RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_CS,
  401.                 (RtPointer)ricolor, RI_NULL);
  402.         else if(!colorsdefined && !normalsdefined)
  403.             RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_NULL);
  404.         else RiPolygon(p->n_vertices, RI_P, (RtPointer)ript, RI_CS, 
  405.             (RtPointer)ricolor, RI_N, (RtPointer)rinormal, RI_NULL);
  406.         
  407.         } /* for */
  408.         
  409.         RiAttributeEnd();
  410.         
  411.     } /* APF_FACEDRAW */ 
  412.     
  413.     if (flag & APF_EDGEDRAW) {
  414.         color = &_mgc->astk->ap.mat->edgecolor;
  415.         RiAttributeBegin();
  416.         RiSurface(RI_CONSTANT, RI_NULL);
  417.         RiColor((float *)color);
  418.         
  419.         mgri_closer();
  420.         
  421.         /* the following can be made MUCH more efficient */
  422.         /* if we buffer groups of points (polygons) and  */
  423.         /* draw all at once.                             */
  424.         for (p = P, i = 0; i < np; i++, p++) {    
  425.         for (j=0, v=p->v; j < (p->n_vertices-1); j++, v++)
  426.             mgri_drawline((HPoint3 *)*v,(HPoint3 *)*(v+1),color);
  427.         mgri_drawline((HPoint3 *)*v,(HPoint3 *)*(p->v),color);
  428.         }
  429.         RiAttributeEnd();
  430.     } /* APF_EDGEDRAW */
  431.     
  432.     } /* MGRI_POLYGONS */
  433.     
  434.     else if(_mgric->polymode == MGRI_POINTSPOLYGONS) {
  435.       
  436.     /* normalize all verticies (colors) */
  437.     if(plflags & PL_HASVCOL) {
  438.         for(i=0, vp=V; i<nv; i++, vp++) {
  439.         mgri_normalize(&(vp->pt), ript[i]);
  440.         //*(Color *)&ricolor[i] = *(Color *)&(vp->vcol);
  441.         }
  442.     }
  443.     else
  444.     for(i=0,vp=V; i<nv; i++, vp++) mgri_normalize(&(vp->pt), ript[i]);
  445.     
  446.     /* check for rippi overflow */
  447.     if(np>rippis) {
  448.         rippis = np + 500;
  449.         rippi = (int *)realloc(rippi, rippis*sizeof(int));
  450.     }
  451.         
  452.     ppi = pvi = 0;
  453.     
  454.     if(flag & APF_FACEDRAW) {
  455.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  456.         int nvert = p->n_vertices;
  457.         
  458.         if(ppi >= _mgric->fflushlimit) {
  459.             RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_CS, ricolor, RI_NULL);
  460.             ppi = pvi = 0;
  461.         }
  462.         rippi[ppi] = nvert;
  463.         /* check for ripvi overflow */
  464.         if(nvert+pvi > ripvis) {
  465.             ripvis = nvert + pvi + 500;
  466.             ripvi = (int *)realloc(ripvi, ripvis*sizeof(int));
  467.         }
  468.         if(plflags & PL_HASPCOL) {
  469.             for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  470.             ripvi[pvi] = (*v) - V;
  471.             *(Color *)&ricolor[pvi] = *(Color *)&(p->pcol);
  472.             }
  473.         } else {
  474.             for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  475.             ripvi[pvi] = (*v) - V; /* int index into vertex list */
  476.             *(Color *)&ricolor[pvi] = *(Color *)&(*v)->vcol; /* already done */
  477.             }
  478.         }
  479.         
  480.         } /* for */
  481.         
  482.         RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_CS, ricolor, RI_NULL);
  483.     
  484.     } /* APF_FACEDRAW */
  485.     
  486.     ppi = pvi = 0;
  487.     
  488.     if(flag & APF_EDGEDRAW) {
  489.         RiAttributeBegin();
  490.         RiGeometricRepresentation(RI_LINES);
  491.         RiColor((float *)&_mgc->astk->mat.edgecolor);
  492.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  493.         int nvert = p->n_vertices;
  494.         
  495.         if(ppi > _mgric->lflushlimit) {
  496.             RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_NULL);
  497.             ppi = pvi = 0;
  498.         }
  499.         rippi[ppi] = nvert;
  500.         /* check for ripvi overflow */
  501.         if(nvert+pvi > ripvis) {
  502.             ripvis = nvert + pvi + 500;
  503.             ripvi = (int *)realloc(ripvi, ripvis*sizeof(int));
  504.         }
  505.         if(plflags & PL_HASPCOL) {
  506.             for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  507.             ripvi[pvi] = (*v) - V;
  508.             }
  509.         } else {
  510.             for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  511.             ripvi[pvi] = (*v) - V;
  512.             *(Color *)&ricolor[i] = *(Color *)&(*v)->vcol; //already done        
  513.             }
  514.         }
  515.         
  516.         } /* for */
  517.         
  518.         RiPointsPolygons(ppi, rippi, ripvi, RI_P, ript, RI_NULL);
  519.         
  520.         RiAttributeEnd();
  521.         
  522.     } /* APF_EDGEDRAW */
  523.  
  524.     } /* MGRI_POINTSPOLYGONS */
  525.  
  526.     else if(_mgric->polymode == MGRI_DEVIDEDPOLYLIST) {
  527.         
  528.     /* create local buffers - these are fixed */
  529.     /* and need not be checked for overflow   */
  530.     static RtPoint gp[GVMAXF+100];  /* vertices */
  531.     static RtPoint gn[GVMAXF+100];  /* normals */
  532.     static RtColor gc[GVMAXF+100];  /* colors */
  533.     static int gvc[GVMAXF];         /* polygon vertex count array */
  534.     static int gvi[GVMAXF+100];     /* vertex index array */ 
  535.     
  536.     /* we will use ript for holding normalized vertices */
  537.     for(i=0,vp=V; i<nv; i++, vp++) mgri_normalize(&(vp->pt), ript[i]);
  538.     
  539.     ppi = pvi = 0;
  540.     
  541.     if(flag & APF_FACEDRAW && plflags & PL_HASVN && plflags & PL_HASPCOL) {
  542.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  543.         nvert = p->n_vertices;
  544.         
  545.         if(pvi+nvert >= GVMAXF) {
  546.             RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn,
  547.             RI_CS, gc, RI_NULL);
  548.             ppi = pvi = 0;
  549.         }
  550.         gvc[ppi] = nvert;
  551.  
  552.         for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  553.             gvi[pvi] = pvi;
  554.             *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)];
  555.             *(Color *)&gc[pvi] = *(Color *)&(p->pcol);
  556.             *(Point3 *)&gn[pvi] = *(Point3 *)&((*v)->vn);
  557.         }
  558.         
  559.         } /* for */
  560.         
  561.         RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn,
  562.         RI_CS, gc, RI_NULL);
  563.     
  564.     }
  565.  
  566.     else
  567.     if(flag & APF_FACEDRAW && plflags & PL_HASVN && plflags & PL_HASVCOL) {
  568.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  569.         nvert = p->n_vertices;
  570.         
  571.         if(pvi+nvert >= GVMAXF) {
  572.             RiPointsPolygons(ppi, gvc, gvi, RI_P, gp,
  573.             RI_N, gn, RI_CS, gc, RI_NULL);
  574.             ppi = pvi = 0;
  575.         }
  576.         gvc[ppi] = nvert;
  577.  
  578.         for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  579.             gvi[pvi] = pvi;
  580.             *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)];
  581.             *(Point3 *)&gn[pvi] = *(Point3 *)&((*v)->vn);
  582.             *(Color *)&gc[pvi] = *(Color *)&((*v)->vcol);
  583.         }
  584.         
  585.         } /* for */
  586.         
  587.         RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn,
  588.         RI_CS, gc, RI_NULL);
  589.     
  590.     }
  591.  
  592.     else
  593.     if(flag & APF_FACEDRAW && plflags & PL_HASVN) {
  594.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  595.         nvert = p->n_vertices;
  596.         
  597.         if(pvi+nvert >= GVMAXF) {
  598.             RiPointsPolygons(ppi, gvc, gvi, RI_P, gp,
  599.             RI_N, gn, RI_NULL);
  600.             ppi = pvi = 0;
  601.         }
  602.         gvc[ppi] = nvert;
  603.  
  604.         for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  605.             gvi[pvi] = pvi;
  606.             *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)];
  607.             *(Point3 *)&gn[pvi] = *(Point3 *)&((*v)->vn);
  608.         }
  609.         
  610.         } /* for */
  611.         
  612.         RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_N, gn, RI_NULL);
  613.     
  614.     }
  615.  
  616.      else
  617.     if(flag & APF_FACEDRAW && plflags & PL_HASPCOL) {
  618.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  619.         nvert = p->n_vertices;
  620.         
  621.         if(pvi+nvert >= GVMAXF) {
  622.             RiPointsPolygons(ppi, gvc, gvi, RI_P, gp,
  623.             RI_CS, gc, RI_NULL);
  624.             ppi = pvi = 0;
  625.         }
  626.         gvc[ppi] = nvert;
  627.  
  628.         for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  629.             gvi[pvi] = pvi;
  630.             *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)];
  631.             *(Color *)&gc[pvi] = *(Color *)&(p->pcol);
  632.         }
  633.         
  634.         } /* for */
  635.         
  636.         RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_CS, gc, RI_NULL);
  637.     
  638.     }
  639.  
  640.      else
  641.     if(flag & APF_FACEDRAW && plflags & PL_HASVCOL) {
  642.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  643.         nvert = p->n_vertices;
  644.         
  645.         if(pvi+nvert >= GVMAXF) {
  646.             RiPointsPolygons(ppi, gvc, gvi, RI_P, gp,
  647.             RI_CS, gc, RI_NULL);
  648.             ppi = pvi = 0;
  649.         }
  650.         gvc[ppi] = nvert;
  651.  
  652.         for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  653.             gvi[pvi] = pvi;
  654.             *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)];
  655.             *(Color *)&gc[pvi] = *(Color *)&((*v)->vcol);
  656.         }
  657.         
  658.         } /* for */
  659.         
  660.         RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_CS, gc, RI_NULL);
  661.     
  662.     }
  663.  
  664.      else
  665.     if(flag & APF_FACEDRAW) {
  666.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  667.         nvert = p->n_vertices;
  668.         
  669.         if(pvi+nvert >= GVMAXF) {
  670.             RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL);
  671.             ppi = pvi = 0;
  672.         }
  673.         gvc[ppi] = nvert;
  674.  
  675.         for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  676.             gvi[pvi] = pvi;
  677.             *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)];
  678.         }
  679.         
  680.         } /* for */
  681.         
  682.         RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL);
  683.     
  684.     }
  685.  
  686.   
  687.     ppi = pvi = 0;
  688.  
  689.     if(flag & APF_EDGEDRAW) {
  690.         RiAttributeBegin();
  691.         RiGeometricRepresentation(RI_LINES);
  692.         mgri_closer();
  693.         
  694.         color = &_mgc->astk->ap.mat->edgecolor;
  695.         RiColor((float *)color);
  696.  
  697.         for(p = P, i=0; i < np; i++, p++, ppi++) {
  698.         int nvert = p->n_vertices;
  699.         
  700.         if(pvi+nvert >= GVMAXF) {
  701.             RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL);
  702.             ppi = pvi = 0;
  703.         }
  704.         gvc[ppi] = nvert;
  705.  
  706.         for(j=0, v=p->v; j < nvert; j++, v++, pvi++) {
  707.             gvi[pvi] = pvi;
  708.             *(Point3 *)&gp[pvi] = *(Point3 *)&ript[((*v) - V)];
  709.         }
  710.         
  711.         } /* for */
  712.         
  713.         RiPointsPolygons(ppi, gvc, gvi, RI_P, gp, RI_NULL);
  714.         RiAttributeEnd();
  715.     }
  716.  
  717.     }
  718.  
  719.     /* polylist methods share a common normal
  720.      * drawing routine, if that's selected. However
  721.      * since MGRI_POINTSPOLYGONS method relies on
  722.      * qrman computing normals, showing these normals
  723.      * in that mode is misleading. Suggestions?
  724.      */
  725.     if (flag & APF_NORMALDRAW) {
  726.     Color *color = &_mgc->astk->mat.normalcolor;
  727.     RiAttributeBegin();
  728.     RiSurface(RI_CONSTANT, RI_NULL);
  729.     RiColor((float *)color);
  730.     if (plflags & PL_HASPN) {
  731.         for (p = P, i = 0; i < np; i++, p++)
  732.         for (j=0, v=p->v; j < p->n_vertices; j++, v++)
  733.         mgri_drawnormal(&(*v)->pt, &p->pn, color);
  734.     } else if (plflags & PL_HASVN) {
  735.         for (vp = V, i = 0; i < nv; i++, vp++) {
  736.         mgri_drawnormal(&vp->pt, &vp->vn, color);
  737.         }
  738.     }
  739.     RiAttributeEnd();
  740.     }
  741.  
  742. }
  743.  
  744. /* There is a basic problem now with 4-d points and 3-d normal vectors.
  745. For now, we'll just ignore the 4-th coordinate of the point when 
  746. computing the tip of the normal vector.  This will work OK with all
  747. existing models, but for genuine 4-d points it won't work.  But,
  748. come to think of it, what is the correct interpretation of the
  749. normal vector when the points live in 4-d?
  750. */
  751. /* also, there is the fact that this function now requires a color */
  752. void
  753. mgri_drawnormal(HPoint3 *p, Point3 *n, Color *theColor) {    
  754.     HPoint3 scaledn,end, tp;
  755.     float scale;
  756.     
  757.     scale = _mgc->astk->ap.nscale;
  758.     if (p->w < 0.0) return;
  759.     HPt3Normalize(p, &tp);
  760.     Pt3Mul(scale, n, &scaledn);
  761.     scaledn.w = 0.0;
  762.     HPt3Add(&tp, &scaledn, &end);
  763.     
  764.     mgri_drawline(&tp,&end,theColor);
  765.     
  766. }
  767.  
  768. void
  769. mgri_drawline(HPoint3 *p1, HPoint3 *p2, Color *theColor)
  770. {
  771.     /*
  772.      * Don't call this function directly unless you have set
  773.      * a constant surface, otherwise the line will inherit the
  774.      * current surface attributes.
  775.      */
  776.  
  777. // following is special case for thick lines
  778. // disabled for now - this doesn't work well
  779. //   if(_mgc->astk->ap.linewidth>1.0)
  780. //    mgri_drawPline(p1, p2);
  781.  
  782. //following is old way to draw lines
  783. //    mgri_normalize(p1, ript[0]);
  784. //    mgri_normalize(p2, ript[1]);
  785. //    RiLine(2, RI_P, (RtPointer)ript, RI_NULL);
  786.  
  787. //following is newer FASTER way to draw lines (buffering)
  788. //however, I'm not sure if the colors will work right
  789.     plvca[_mgric->plni++] = 2;
  790.     plvia[_mgric->plvi] = _mgric->plvi;
  791.     plvia[_mgric->plvi+1] = _mgric->plvi+1;
  792.     *(Color *)&plc[_mgric->plvi] = *(Color *)theColor;
  793.     *(Color *)&plc[_mgric->plvi+1] = *(Color *)theColor;
  794.     mgri_normalize(p1, plp[_mgric->plvi]);
  795.     mgri_normalize(p2, plp[_mgric->plvi+1]);
  796.     _mgric->plvi+=2;
  797.  
  798.     if(_mgric->plvi> _mgric->plbuffsize) mgri_plflush();
  799.  
  800. }
  801.  
  802. /*-----------------------------------------------------------------------
  803.  * Function:    mgri_drawPline
  804.  * Description:    Experimental thick line drawing procedure
  805.  * Author:    wisdom
  806.  * Date:    Sat Feb 20 15:47:11 CST 1993
  807.  * Notes:
  808.  */
  809. void
  810. mgri_drawPline(HPoint3 *p1, HPoint3 *p2)
  811. {
  812.     Transform V;
  813.     Transform P2S,O2S, O2P, P2O, S2O;
  814.     int xsize, ysize;
  815.     HPoint3 pnts[4], pnts2[4];
  816.     HPoint3 s1, s2;
  817.     int i;
  818.     float dx,dy,k, len;
  819.  
  820.     /* This code will simulate line drawing in Photorman */
  821.     /* create obj->proj transform */
  822.     CamView(_mgc->cam, V);        /* world->proj */
  823.     TmConcat(_mgc->xstk->T, V, O2P);    /* obj->proj */
  824.     
  825.     /* create obj->screen transform */
  826.     WnGet(_mgc->win, WN_XSIZE, &xsize);
  827.     WnGet(_mgc->win, WN_YSIZE, &ysize);
  828.     TmScale(P2S, (float)xsize, (float)ysize, 1.0);
  829.     TmConcat(O2P, P2S, O2S);
  830.     
  831.     /* translate & dehomogenize line endpoints from object to screen */
  832.     HPt3TransPt3(_mgc->O2S, p1, &s1);
  833.     HPt3TransPt3(_mgc->O2S, p2, &s2);
  834.  
  835.     dy = s2.y - s1.y;
  836.     dx = s2.x - s1.x;
  837.     len = hypot(dy,dx);
  838.     k = _mgc->astk->ap.linewidth / len;
  839.     
  840.     pnts[0].x = s1.x - dy * k;
  841.     pnts[0].y = s1.y + dx * k;
  842.     pnts[1].x = s1.x + dy * k;
  843.     pnts[1].y = s1.y - dx * k;
  844.     pnts[2].x = s2.x + dy * k;
  845.     pnts[2].y = s2.y - dx * k;
  846.     pnts[3].x = s2.x - dy * k;
  847.     pnts[3].y = s2.y + dx * k;
  848.         
  849.     pnts[0].z = s1.z;
  850.     pnts[1].z = s1.z;
  851.     pnts[2].z = s2.z;
  852.     pnts[3].z = s2.z;
  853.     
  854.     for (i=0; i<4; ++i) pnts[i].w = 1.0;
  855.          
  856.     /* now project back... */
  857.     /* first, find S2O transform */
  858.     TmInvert(O2S, S2O);
  859.     
  860.     /* now transform screen coords to object coords */
  861.     for(i=0;i<4;i++) {
  862.     HPt3Transform(_mgc->S2O, &pnts[i], &pnts[i]);
  863.     HPt3Normalize(&pnts[i], &pnts[i]);
  864.     }
  865.  
  866.     /* DRAW HERE */
  867.     RiPolygon(4, RI_P, (RtPointer)pnts, RI_NULL);
  868. }
  869.  
  870. /*-----------------------------------------------------------------------
  871.  * Function:    mgri_drawpoint
  872.  * Description: draws a point for rman.
  873.  * Returns:    nothing
  874.  * Author:    wisdom
  875.  * Date:    Fri Mar 13 15:04:01 CST 1992    
  876.  * Notes:    This is now done in mgri_polyline
  877.  */
  878. void
  879. mgri_drawpoint(HPoint3 *p)
  880. {
  881.     mgri_normalize(p, ript[0]);
  882.     //RiLine(1, RI_P, &ript, RI_NULL); << This won't draw point in right color!
  883.     bcopy( ript[0], ript[1], sizeof(RtPoint));
  884.     RiLine(2, RI_P, (RtPointer)ript, RI_NULL);
  885.  
  886. }
  887.  
  888. void
  889. mgri_closer()
  890. {
  891.     Transform Tscale, T1, T2, T3, Tcloser;
  892.     float scaleby;
  893.     
  894.     if(!_mgc->zfnudge) return;
  895.     
  896.     scaleby = 1.-(_mgc->zfnudge*100.);
  897.     TmScale(Tscale, scaleby, scaleby, scaleby);
  898.     TmConcat(_mgc->xstk->T, _mgc->W2C, T1);
  899.     TmConcat(T1, Tscale, T2);
  900.     TmConcat(T2, _mgc->C2W, Tcloser);
  901.  
  902.     RiTransform(Tcloser);
  903. }
  904.